<!DOCTYPE html>
            
<HTML>
<HEAD>
<meta name="booktitle" content="Developing Applications With Objective Caml" >
 <meta charset="ISO-8859-1"><meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0">
<META name="GENERATOR" content="hevea 1.05-7 of 2000-02-24">
<META NAME="Author" CONTENT="Christian.Queinnec@lip6.fr">
<LINK rel=stylesheet type="text/css" href="videoc-ocda.css">
<script language="JavaScript" src="videoc.js"><!--
//--></script>
<TITLE>
 Creating and modifying Objective CAML values from C
</TITLE>
</HEAD>
<BODY class="regularBody">
<A HREF="book-ora115.html"><IMG SRC ="previous_motif.gif" ALT="Previous"></A>
<A HREF="index.html"><IMG SRC ="contents_motif.gif" ALT="Contents"></A>
<A HREF="book-ora117.html"><IMG SRC ="next_motif.gif" ALT="Next"></A>
<HR>

<H2> Creating and modifying Objective CAML values from&nbsp;C</H2>
<A NAME="@concepts272"></A>
A C function called from Objective CAML can modify its arguments in place,
or return a newly-created value. This value must match the 
Objective CAML type for the function result. For base types, several C
macros are provided to convert a C datum to an Objective CAML value.
For structured types, the new value must be allocated in the Objective CAML
heap, with the correct size, and its fields initialized with values of
the correct types. Considerable care is required here: it is easy to
construct bad values from C, and these bad values may crash
the Objective CAML program.<BR>
<BR>
Any allocation in the Objective CAML heap can trigger a garbage collection,
which will deallocate unused memory blocks and may move live blocks.
Therefore, any Objective CAML value manipulated from C must be registered
with the Objective CAML garbage collector, if they are to survive the
allocation of a new block. These values must be treated as extra
memory roots by the garbage collector. To this end, several macros
are provided for registering extra roots with the garbage collector.<BR>
<BR>
Finally, C code can allocate Objective CAML heap blocks that contain C data
instead of Objective CAML values. This C data will then benefit from
Objective CAML's automatic memory management. If the C data requires
explicit deallocation, a finalization function can be attached to the
heap block.<BR>
<BR>
<A NAME="toc154"></A>
<H3> Modifying Objective CAML values</H3>The following macros allow the creation of immediate Objective CAML values from the
corresponding C data, and the modification of structured values in place.<BR>
<BR>
<BLOCKQUOTE><DIV ALIGN=center><HR WIDTH="80%" SIZE=2></DIV>
<DIV ALIGN=center>
<TABLE BORDER=1 CELLSPACING=0 CELLPADDING=1>
<TR><TD  ALIGN=left NOWRAP>&nbsp;</TD>
<TD  ALIGN=left NOWRAP>&nbsp;</TD>
</TR>
<TR><TD  ALIGN=left NOWRAP><TT>Val_long(l)</TT></TD>
<TD  ALIGN=left NOWRAP>return the value representing the long integer <TT>l</TT></TD>
</TR>
<TR><TD  ALIGN=left NOWRAP><TT>Val_int(i)</TT></TD>
<TD  ALIGN=left NOWRAP>return the value representing the integer <TT>l</TT></TD>
</TR>
<TR><TD  ALIGN=left NOWRAP><TT>Val_bool(x)</TT></TD>
<TD  ALIGN=left NOWRAP>return <TT>false</TT> if <TT>x=0</TT>, <TT>true</TT> otherwise</TD>
</TR>
<TR><TD  ALIGN=left NOWRAP><TT>Val_true</TT></TD>
<TD  ALIGN=left NOWRAP>the representation of <TT>true</TT></TD>
</TR>
<TR><TD  ALIGN=left NOWRAP><TT>Val_false</TT></TD>
<TD  ALIGN=left NOWRAP>the representation of <TT>false</TT></TD>
</TR>
<TR><TD  ALIGN=left NOWRAP><TT>Val_unit</TT></TD>
<TD  ALIGN=left NOWRAP>the representation of <TT>()</TT></TD>
</TR>
<TR><TD  ALIGN=left NOWRAP>&nbsp;</TD>
<TD  ALIGN=left NOWRAP>&nbsp;</TD>
</TR>
<TR><TD  ALIGN=left NOWRAP><TT>Store_field(b,n,v)</TT></TD>
<TD  ALIGN=left NOWRAP>store the value <TT>v</TT> in the <TT>n</TT>-th
field of block <TT>b</TT></TD>
</TR>
<TR><TD  ALIGN=left NOWRAP><TT>Store_double_field(b,n,d)</TT></TD>
<TD  ALIGN=left NOWRAP>store the float <TT>d</TT> in the
<TT>n</TT>-th field of the float array <TT>b</TT></TD>
</TR></TABLE>
</DIV>
<BR>
<DIV ALIGN=center>Figure 12.10: Creation of immediate values and modification of structured blocks.</DIV><BR>

<A NAME="fig-cremod-imm-C"></A>
<DIV ALIGN=center><HR WIDTH="80%" SIZE=2></DIV></BLOCKQUOTE>Moreover, the macros <TT>Byte</TT> and <TT>Byte_u</TT> can be used on the
left-hand side of an assignment to modify the characters of a string.
The <TT>Field</TT> macro can also be used for assignment on blocks with
tag <TT>Abstract_tag</TT> or <TT>Final_tag</TT>; use <TT>Store_field</TT>
for blocks with tag between <TT>0</TT> and <TT>No_scan_tag-1</TT>.
The following function reverses a character string in place:<BR>
<BR>


<PRE>
<CODE>#include &lt;caml/mlvalues.h&gt;</CODE><BR><CODE>value swap_char(value v, int i, int j)  </CODE><BR><CODE>  { char c=Byte(v,i); Byte(v,i)=Byte(v,j); Byte(v,j)=c; }</CODE><BR><CODE>value swap_string (value v)</CODE><BR><CODE>{ </CODE><BR><CODE>  int i,j,t = string_length(v) ;</CODE><BR><CODE>  for (i=0,j=t-1; i&lt;t/2; i++,j--)  swap_char(v,i,j) ;</CODE><BR><CODE>  return v ;</CODE><BR><CODE>}</CODE><BR>

</PRE>



<PRE><BR># <B>external</B><CODE> </CODE>mirror<CODE> </CODE><CODE>:</CODE><CODE> </CODE>string<CODE> </CODE>-&gt;<CODE> </CODE>string<CODE> </CODE><CODE>=</CODE><CODE> </CODE><CODE>"swap_string"</CODE><CODE> </CODE>;;<BR><CODE>external mirror : string -&gt; string = "swap_string"</CODE><BR># mirror<CODE> </CODE><CODE>"abcdefg"</CODE><CODE> </CODE>;;<BR><CODE>- : string = "gfedcba"</CODE><BR>

</PRE>
<BR>
<BR>
<A NAME="toc155"></A>
<H3> Allocating new blocks</H3>
The functions listed in figure <A HREF="book-ora116.html#fig-alloc-C">12.11</A> allocate new blocks
in the Objective CAML heap. 
<BLOCKQUOTE><DIV ALIGN=center><HR WIDTH="80%" SIZE=2></DIV>
<DIV ALIGN=center>
<TABLE BORDER=1 CELLSPACING=0 CELLPADDING=1>
<TR><TD  ALIGN=left NOWRAP>&nbsp;</TD>
<TD  ALIGN=left NOWRAP>&nbsp;</TD>
</TR>
<TR><TD  ALIGN=left NOWRAP><TT>alloc(n, t)</TT></TD>
<TD  ALIGN=left NOWRAP>return a new block of size <TT>n</TT> words and tag <TT>t</TT></TD>
</TR>
<TR><TD  ALIGN=left NOWRAP><TT>alloc_tuple(n)</TT></TD>
<TD  ALIGN=left NOWRAP>same, with tag 0</TD>
</TR>
<TR><TD  ALIGN=left NOWRAP><TT>alloc_string(n)</TT></TD>
<TD  ALIGN=left NOWRAP>return an uninitialized string of length <TT>n</TT> characters</TD>
</TR>
<TR><TD  ALIGN=left NOWRAP><TT>copy_string(s)</TT></TD>
<TD  ALIGN=left NOWRAP>return a string initialized with the C string
<TT>s</TT></TD>
</TR>
<TR><TD  ALIGN=left NOWRAP><TT>copy_double(d)</TT></TD>
<TD  ALIGN=left NOWRAP>return a block containing the double float
<TT>d</TT></TD>
</TR>
<TR><TD  ALIGN=left NOWRAP><TT>alloc_array(f, a)</TT></TD>
<TD  ALIGN=left NOWRAP>return a block representing an array, initialized
by applying</TD>
</TR>
<TR><TD  ALIGN=left NOWRAP>&nbsp;</TD>
<TD  ALIGN=left NOWRAP>the conversion function <TT>f</TT> to each element of the C array of</TD>
</TR>
<TR><TD  ALIGN=left NOWRAP>&nbsp;</TD>
<TD  ALIGN=left NOWRAP>pointers <TT>a</TT>, null-terminated.</TD>
</TR>
<TR><TD  ALIGN=left NOWRAP><TT>copy_string_array(p)</TT></TD>
<TD  ALIGN=left NOWRAP>return a block representing an array of
strings, obtained</TD>
</TR>
<TR><TD  ALIGN=left NOWRAP>&nbsp;</TD>
<TD  ALIGN=left NOWRAP>from the C string array <TT>p</TT> (of type <TT>char **</TT>),
null-terminated.</TD>
</TR></TABLE>
</DIV>
<BR>
<DIV ALIGN=center>Figure 12.11: Functions for allocating blocks.</DIV><BR>

<A NAME="fig-alloc-C"></A>
<DIV ALIGN=center><HR WIDTH="80%" SIZE=2></DIV></BLOCKQUOTE>
The function <TT>alloc_array</TT> takes an array of pointers <TT>a</TT>,
terminated by a null pointer, and a conversion function <TT>f</TT>
taking a pointer and returning a value. The result of <TT>alloc_array</TT> is an Objective CAML array containing the results of applying
<TT>f</TT> in turn to each pointer in <TT>a</TT>. In the following example,
the function <TT>make_str_array</TT> uses <TT>alloc_array</TT> to convert
a C array of strings.<BR>
<BR>


<PRE>
<CODE>#include &lt;caml/mlvalues.h&gt;</CODE><BR><CODE>value make_str (char *s) { return copy_string(s); }</CODE><BR><CODE>value make_str_array (char **p) { return alloc_array(make_str,p) ; }</CODE><BR>

</PRE>
<BR>
<BR>
It is sometimes necessary to allocate blocks of size 0, for instance
to represent an empty Objective CAML array. Such a block is called an
atom.


<PRE><BR># inspect<CODE> </CODE><CODE>[|</CODE><CODE> </CODE><CODE>|]</CODE><CODE> </CODE>;;<BR><CODE>....memory block: size=0  -  structured block (tag=0):</CODE><BR><CODE>- : '_a array = [||]</CODE><BR>

</PRE>
<BR>
<BR>
Because atoms are allocated statically and do not reside in
the dynamic part of the Objective CAML heap,
the allocation functions in figure <A HREF="book-ora116.html#fig-alloc-C">12.11</A> must not be
used to allocate atoms. Instead, atoms are created in C by the macro
<TT>Atom(t)</TT>, where <TT>t</TT> is the desired tag for the block of size
0. <BR>
<BR>
<A NAME="toc156"></A>
<H3> Storing C data in the Objective CAML heap</H3>
It is sometimes convenient to use the Objective CAML heap to store arbitrary C data
that does not respect the constraints imposed by the garbage collector.
In this case, blocks with tag <TT>Abstract_tag</TT> must be used.<BR>
<BR>
A natural example is the manipulation of native C integers
(of size 32 or 64 bits) in Objective CAML.
Since these integers are not tagged as the
Objective CAML garbage collector expects, they must be kept in one-word heap
blocks with tag <TT>Abstract_tag</TT>.<BR>
<BR>


<PRE>
<CODE>#include &lt;caml/mlvalues.h&gt;</CODE><BR><CODE>#include &lt;stdio.h&gt;</CODE><BR><BR><CODE>value Cint_of_OCAMLint (value v)</CODE><BR><CODE>{</CODE><BR><CODE>  value res = alloc(1,Abstract_tag) ;</CODE><BR><CODE>  Field(res,0) = Long_val(v) ;</CODE><BR><CODE>  return res ;</CODE><BR><CODE>}</CODE><BR><BR><CODE>value OCAMLint_of_Cint (value v)  { return Val_long(Field(v,0)) ; }</CODE><BR><BR><CODE>value Cplus (value v1,value v2) </CODE><BR><CODE>{</CODE><BR><CODE>  value res = alloc(1,Abstract_tag) ;</CODE><BR><CODE>  Field(res,0) = Field(v1,0) + Field(v2,0) ;</CODE><BR><CODE>  return res ;</CODE><BR><CODE>}</CODE><BR><BR><CODE>value printCint (value v)</CODE><BR><CODE>{</CODE><BR><CODE>  printf ("%d",(long) Field(v,0)) ; fflush(stdout) ; </CODE><BR><CODE>  return Val_unit ;</CODE><BR><CODE>}</CODE><BR>

</PRE>



<PRE><BR># <B>type</B><CODE> </CODE>cint<CODE> </CODE><BR><CODE> </CODE><B>external</B><CODE> </CODE>cint_of_int<CODE> </CODE><CODE>:</CODE><CODE> </CODE>int<CODE> </CODE>-&gt;<CODE> </CODE>cint<CODE> </CODE><CODE>=</CODE><CODE> </CODE><CODE>"Cint_of_OCAMLint"</CODE><BR><CODE> </CODE><B>external</B><CODE> </CODE>int_of_cint<CODE> </CODE><CODE>:</CODE><CODE> </CODE>cint<CODE> </CODE>-&gt;<CODE> </CODE>int<CODE> </CODE><CODE>=</CODE><CODE> </CODE><CODE>"OCAMLint_of_Cint"</CODE><CODE> </CODE><BR><CODE> </CODE><B>external</B><CODE> </CODE>plus_cint<CODE> </CODE><CODE>:</CODE><CODE> </CODE>cint<CODE> </CODE>-&gt;<CODE> </CODE>cint<CODE> </CODE>-&gt;<CODE> </CODE>cint<CODE> </CODE><CODE>=</CODE><CODE> </CODE><CODE>"Cplus"</CODE><BR><CODE> </CODE><B>external</B><CODE> </CODE>print_cint<CODE> </CODE><CODE>:</CODE><CODE> </CODE>cint<CODE> </CODE>-&gt;<CODE> </CODE>unit<CODE> </CODE><CODE>=</CODE><CODE> </CODE><CODE>"printCint"</CODE><CODE> </CODE>;;<BR>

</PRE>
<BR>
<BR>
We can now work on native C integers, without losing the use of the tag bit,
while remaining compatible with Objective CAML's garbage collector.
However, such integers are heap-allocated, instead of being immediate
values, which renders arithmetic operations less efficient.


<PRE><BR># <B>let</B><CODE> </CODE>a<CODE> </CODE><CODE>=</CODE><CODE> </CODE><CODE>1</CODE><CODE>0</CODE><CODE>0</CODE><CODE>0</CODE><CODE>0</CODE><CODE>0</CODE><CODE>0</CODE><CODE>0</CODE><CODE>0</CODE><CODE>0</CODE><CODE> </CODE>;;<BR><CODE>val a : int = 1000000000</CODE><BR># a<CODE>+</CODE>a<CODE> </CODE>;;<BR><CODE>- : int = -147483648</CODE><BR># <B>let</B><CODE> </CODE>c<CODE> </CODE><CODE>=</CODE><CODE> </CODE><B>let</B><CODE> </CODE>b<CODE> </CODE><CODE>=</CODE><CODE> </CODE>cint_of_int<CODE> </CODE>a<CODE> </CODE><B>in</B><CODE> </CODE>plus_cint<CODE> </CODE>b<CODE> </CODE>b<CODE> </CODE>;;<BR><CODE>val c : cint = &lt;abstr&gt;</CODE><BR># print_cint<CODE> </CODE>c<CODE> </CODE>;<CODE> </CODE>print_newline<CODE> </CODE>()<CODE> </CODE>;;<BR><CODE>2000000000</CODE><BR><CODE>- : unit = ()</CODE><BR># int_of_cint<CODE> </CODE>c<CODE> </CODE>;;<BR><CODE>- : int = -147483648</CODE><BR>

</PRE>
<BR>
<BR>

<H4> Finalization functions</H4><A NAME="IC-finalisation"></A>
<A NAME="@concepts273"></A>
<A NAME="@concepts274"></A>
Abstract blocks can also contain pointers to memory blocks allocated
outside the Objective CAML heap. We know that Objective CAML blocks that are no
longer used by the program are deallocated by the garbage collector.
But what happens to a block allocated in the C heap and referenced by
an abstract block that was reclaimed by the GC? To avoid memory
leaks, we can associate a finalization function to the
abstract block; this function is called by the GC before reclaiming
the abstract block.<BR>
<BR>
An abstract block with an attached finalization function is allocated
via the function <TT>alloc_final (n, f, used, max) </TT>.
<UL>
<LI>
 <TT>n</TT> is the size of the block, in words. The first word of
the block is used to store the finalization function; hence the size
occupied by the user data must be increased by one word.

<LI> <TT>f</TT> is the finalization function itself, with type
<TT>void f (value)</TT>. It receives the abstract block as argument,
just before this block is reclaimed by the GC.

<LI> <TT>used</TT> represents the memory space (outside the Objective CAML heap)
occupied by the C data. <TT>used</TT> must be &lt;= <TT>max</TT>.

<LI> <TT>max</TT> is the maximum memory space outside the Objective CAML heap
that we tolerate not being reclaimed immediately.
</UL>
For efficiency reasons, the Objective CAML garbage collector does not
reclaim heap blocks as soon as they become unused, but some time
later. The ratio <TT>used/max</TT> controls the proportion of finalized
abstract blocks that the garbage collector may leave allocated while
they are no longer used. A ratio of 0 (that is, <TT>used = 0</TT>)
lets the garbage collector work at its usual pace; higher ratios
(no greater than 1) cause it to work harder and spend more CPU time
finding unused finalized blocks and reclaiming them.<BR>
<BR>
The following program manipulates arrays of C integers allocated in
the C heap via <TT>malloc</TT>. To allow the Objective CAML garbage collector
to reclaim these arrays automatically, the <TT>create</TT> function wraps
them in a finalized abstract block, containing both a pointer to the
array and the finalization function <TT>finalize_it</TT>.<BR>
<BR>


<PRE>
<CODE>#include &lt;malloc.h&gt;</CODE><BR><CODE>#include &lt;stdio.h&gt;</CODE><BR><CODE>#include &lt;caml/mlvalues.h&gt;</CODE><BR><BR><CODE>typedef struct { </CODE><BR><CODE>        int size ;</CODE><BR><CODE>        long * tab ; } IntTab ;</CODE><BR><BR><CODE>IntTab *alloc_it (int s)</CODE><BR><CODE>{ </CODE><BR><CODE>  IntTab *res = malloc(sizeof(IntTab)) ;</CODE><BR><CODE>  res-&gt;size = s ;</CODE><BR><CODE>  res-&gt;tab = (long *) malloc(sizeof(long)*s) ;</CODE><BR><CODE>  return res ;</CODE><BR><CODE>}</CODE><BR><CODE>void free_it (IntTab *p)  { free(p-&gt;tab) ; free(p) ; }</CODE><BR><CODE>void put_it (int n,long q,IntTab *p)  { p-&gt;tab[n] = q ; }</CODE><BR><CODE>long get_it (int n,IntTab *p)  { return p-&gt;tab[n]; }</CODE><BR><BR><CODE>void finalize_it (value v)  </CODE><BR><CODE>{ </CODE><BR><CODE>  IntTab *p = (IntTab *) Field(v,1) ;</CODE><BR><CODE>  int i;</CODE><BR><CODE>  printf("reclamation of an IntTab by finalization [") ;</CODE><BR><CODE>  for (i=0;i&lt;p-&gt;size;i++) printf("%d ",p-&gt;tab[i]) ;</CODE><BR><CODE>  printf("]\n"); fflush(stdout) ;</CODE><BR><CODE>  free_it ((IntTab *) Field(v,1)) ; </CODE><BR><CODE>}</CODE><BR><CODE>value create (value s)</CODE><BR><CODE>{</CODE><BR><CODE>  value block ;</CODE><BR><CODE>  block = alloc_final (2, finalize_it,Int_val(s)*sizeof(IntTab),100000) ;</CODE><BR><CODE>  Field(block,1) = (value) alloc_it(Int_val(s)) ;</CODE><BR><CODE>  return block ;</CODE><BR><CODE>}</CODE><BR><CODE>value put (value n,value q,value t)  </CODE><BR><CODE>{ </CODE><BR><CODE>  put_it (Int_val(n), Long_val(q), (IntTab *) Field(t,1)) ; </CODE><BR><CODE>  return Val_unit ;</CODE><BR><CODE>}</CODE><BR><CODE>value get (value n,value t)  </CODE><BR><CODE>{ </CODE><BR><CODE>  long res = get_it (Int_val(n), (IntTab *) Field(t,1)) ;</CODE><BR><CODE>  return Val_long(res) ;</CODE><BR><CODE>}</CODE><BR>

</PRE>

The C functions visible from Objective CAML are: <TT>create</TT>,
<TT>put</TT> and <TT>get</TT>.


<PRE><BR># <B>type</B><CODE> </CODE>c_int_array<BR><CODE> </CODE><B>external</B><CODE> </CODE>cia_create<CODE> </CODE><CODE>:</CODE><CODE> </CODE>int<CODE> </CODE>-&gt;<CODE> </CODE>c_int_array<CODE> </CODE><CODE>=</CODE><CODE> </CODE><CODE>"create"</CODE><BR><CODE> </CODE><B>external</B><CODE> </CODE>cia_get<CODE> </CODE><CODE>:</CODE><CODE> </CODE>int<CODE> </CODE>-&gt;<CODE> </CODE>c_int_array<CODE> </CODE>-&gt;<CODE> </CODE>int<CODE> </CODE><CODE>=</CODE><CODE> </CODE><CODE>"get"</CODE><BR><CODE> </CODE><B>external</B><CODE> </CODE>cia_put<CODE> </CODE><CODE>:</CODE><CODE> </CODE>int-&gt;<CODE> </CODE>int<CODE> </CODE>-&gt;<CODE> </CODE>c_int_array<CODE> </CODE>-&gt;<CODE> </CODE>unit<CODE> </CODE><CODE>=</CODE><CODE> </CODE><CODE>"put"</CODE><CODE> </CODE>;;<BR>

</PRE>
<BR>
<BR>
We can now manipulate our new data structure from Objective CAML:


<PRE><BR># <B>let</B><CODE> </CODE>tbl<CODE> </CODE><CODE>=</CODE><CODE> </CODE>cia_create<CODE> </CODE><CODE>1</CODE><CODE>0</CODE><CODE> </CODE><B>and</B><CODE> </CODE>tbl2<CODE> </CODE><CODE>=</CODE><CODE> </CODE>cia_create<CODE> </CODE><CODE>1</CODE><CODE>0</CODE><CODE> </CODE><BR><CODE> </CODE><B>in</B><CODE> </CODE><B>for</B><CODE> </CODE>i<CODE>=</CODE><CODE>0</CODE><CODE> </CODE><B>to</B><CODE> </CODE><CODE>9</CODE><CODE> </CODE><B>do</B><CODE> </CODE>cia_put<CODE> </CODE>i<CODE> </CODE><TT>(</TT>i<CODE>*</CODE><CODE>2</CODE><TT>)</TT><CODE> </CODE>tbl<CODE> </CODE><B>done</B><CODE> </CODE>;<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>for</B><CODE> </CODE>i<CODE>=</CODE><CODE>0</CODE><CODE> </CODE><B>to</B><CODE> </CODE><CODE>9</CODE><CODE> </CODE><B>do</B><CODE> </CODE>print_int<CODE> </CODE><TT>(</TT>cia_get<CODE> </CODE>i<CODE> </CODE>tbl<TT>)</TT><CODE> </CODE>;<CODE> </CODE>print_string<CODE> </CODE><CODE>" "</CODE><CODE> </CODE><B>done</B><CODE> </CODE>;<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE>print_newline<CODE> </CODE>()<CODE> </CODE>;<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>for</B><CODE> </CODE>i<CODE>=</CODE><CODE>0</CODE><CODE> </CODE><B>to</B><CODE> </CODE><CODE>9</CODE><CODE> </CODE><B>do</B><CODE> </CODE>cia_put<CODE> </CODE><TT>(</TT><CODE>9</CODE><CODE>-</CODE>i<TT>)</TT><CODE> </CODE><TT>(</TT>cia_get<CODE> </CODE>i<CODE> </CODE>tbl<TT>)</TT><CODE> </CODE>tbl2<CODE> </CODE><B>done</B><CODE> </CODE>;<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>for</B><CODE> </CODE>i<CODE>=</CODE><CODE>0</CODE><CODE> </CODE><B>to</B><CODE> </CODE><CODE>9</CODE><CODE> </CODE><B>do</B><CODE> </CODE>print_int<CODE> </CODE><TT>(</TT>cia_get<CODE> </CODE>i<CODE> </CODE>tbl2<TT>)</TT><CODE> </CODE>;<CODE> </CODE>print_string<CODE> </CODE><CODE>" "</CODE><CODE> </CODE><B>done</B><CODE> </CODE>;;<BR><CODE>0 2 4 6 8 10 12 14 16 18 </CODE><BR><CODE>18 16 14 12 10 8 6 4 2 0 - : unit = ()</CODE><BR>

</PRE>
<BR>
<BR>
We now force a garbage collection to check that the finalization
function is called:


<PRE><BR># Gc.full_major<CODE> </CODE>()<CODE> </CODE>;;<BR><CODE>reclaimation of an IntTab by finalization [18 16 14 12 10 8 6 4 2 0 ]</CODE><BR><CODE>reclaimation of an IntTab by finalization [0 2 4 6 8 10 12 14 16 18 ]</CODE><BR><CODE>- : unit = ()</CODE><BR>

</PRE>

In addition to freeing C heap blocks, finalization functions can also
be used to close files, terminate processes, etc.<BR>
<BR>
<A NAME="toc157"></A>
<H3> Garbage collection and C parameters and local variables</H3>A C function can trigger a garbage collection, either during an
allocation (if the heap is full), or voluntarily by calling
 <CODE>void Garbage_collection_function ()</CODE>.<BR>
<BR>
Consider the following example. Can you spot the error?<BR>
<BR>


<PRE>
<CODE>#include &lt;caml/mlvalues.h&gt;</CODE><BR><CODE>#include &lt;caml/memory.h&gt;</CODE><BR><BR><CODE>value identity (value x) </CODE><BR><CODE>{ </CODE><BR><CODE>  Garbage_collection_function() ; </CODE><BR><CODE>  return x; </CODE><BR><CODE>}</CODE><BR>

</PRE>



<PRE><BR># <B>external</B><CODE> </CODE>id<CODE> </CODE><CODE>:</CODE><CODE> </CODE>'a<CODE> </CODE>-&gt;<CODE> </CODE>'a<CODE> </CODE><CODE>=</CODE><CODE> </CODE><CODE>"identity"</CODE><CODE> </CODE>;;<BR><CODE>external id : 'a -&gt; 'a = "identity"</CODE><BR># id<CODE> </CODE><CODE>[</CODE><CODE>1</CODE>;<CODE>2</CODE>;<CODE>3</CODE>;<CODE>4</CODE>;<CODE>5</CODE><CODE>]</CODE><CODE> </CODE>;;<BR><CODE>- : int list = [538917758; 538917752; 538917746; 538917740; 538917734]</CODE><BR>

</PRE>

The list passed as parameter to <TT>id</TT>, hence to the C function
<TT>identity</TT>, can be moved or reclaimed by the garbage collector.
In the example, we forced a garbage collection, but any allocation in
the Objective CAML heap could have triggered a garbage collection as well.
The anonymous list passed to <TT>id</TT> was reclaimed by the
garbage collector, because it is not reachable from the set of known
roots. To avoid this,
any C function that allocates anything in the Objective CAML heap
must tell the garbage collector about the C function's
parameters and local variables of type <TT>value</TT>.
This is achieved by using the macros described next.<BR>
<BR>
For parameters, these macros are used within
the body of the C function as if they were additional
declarations:
<DIV ALIGN=center>
<TABLE CELLSPACING=2 CELLPADDING=0>
<TR><TD  ALIGN=left NOWRAP><TT>CAMLparam1(v)</TT></TD>
<TD  ALIGN=center NOWRAP>:</TD>
<TD  ALIGN=left NOWRAP>for one parameter <TT>v</TT> of type <TT>value</TT></TD>
</TR>
<TR><TD  ALIGN=left NOWRAP><TT>CAMLparam2(v1,v2)</TT></TD>
<TD  ALIGN=center NOWRAP>:</TD>
<TD  ALIGN=left NOWRAP>for two parameters</TD>
</TR>
<TR><TD  ALIGN=left NOWRAP>...</TD>
<TD  ALIGN=center NOWRAP>&nbsp;</TD>
<TD  ALIGN=left NOWRAP>...</TD>
</TR>
<TR><TD  ALIGN=left NOWRAP><TT>CAMLparam5(v1,</TT><TT>...</TT><TT>,v5)</TT></TD>
<TD  ALIGN=center NOWRAP>:</TD>
<TD  ALIGN=left NOWRAP>for five parameters</TD>
</TR>
<TR><TD  ALIGN=left NOWRAP><TT>CAMLparam0</TT> ;</TD>
<TD  ALIGN=center NOWRAP>:</TD>
<TD  ALIGN=left NOWRAP>required when there are no <TT>value</TT> parameters.</TD>
</TR></TABLE>
</DIV>
If the C function has more than five <TT>value</TT> parameters,
the first five are declared with the <TT>CAMLparam5</TT> macro,
and the remaining parameters with the macros <TT>CAMLxparam1</TT>, ..., <TT>CAMLxparam5</TT>, used as many times as
necessary to list all <TT>value</TT> parameters. <BR>
<BR>
<TABLE CELLSPACING=2 CELLPADDING=0>
<TR><TD  ALIGN=left NOWRAP><TT>CAMLparam5(v1,</TT><TT>...</TT><TT>,v5);</TT></TD>
</TR>
<TR><TD  ALIGN=left NOWRAP><TT>CAMLxparam5(v6,</TT><TT>...</TT><TT>,v10);</TT></TD>
</TR>
<TR><TD  ALIGN=left NOWRAP><TT>CAMLxparam2(v11,v12);</TT></TD>
<TD  ALIGN=center NOWRAP>:</TD>
<TD  ALIGN=left NOWRAP>for 12 parameters of type <TT>value</TT></TD>
</TR></TABLE><BR>
For local variables, these macros are used instead of
normal C declarations of the variables.
Local variables of type <TT>value</TT> must also be registered with the
garbage collector, using the macros <TT>CAMLlocal1</TT>,
..., <TT>CAMLlocal5</TT>. An array of values is declared with
<TT>CAMLlocalN(tbl,n)</TT> where <TT>n</TT> is the number of elements
of the array <TT>tbl</TT>. Finally, to return from the C function,
we must use the macro <TT>CAMLreturn</TT> instead of C's <TT>return</TT>
construct.<BR>
<BR>
Here is the corrected version of the previous example:<BR>
<BR>


<PRE>
<CODE>#include &lt;caml/mlvalues.h&gt;</CODE><BR><CODE>#include &lt;caml/memory.h&gt;</CODE><BR><CODE>value identity2 (value x) </CODE><BR><CODE>{ </CODE><BR><CODE>  CAMLparam1(x) ;</CODE><BR><CODE>  Garbage_collection_function() ; </CODE><BR><CODE>  CAMLreturn x; </CODE><BR><CODE>}</CODE><BR>

</PRE>



<PRE><BR># <B>external</B><CODE> </CODE>id<CODE> </CODE><CODE>:</CODE><CODE> </CODE>'a<CODE> </CODE>-&gt;<CODE> </CODE>'a<CODE> </CODE><CODE>=</CODE><CODE> </CODE><CODE>"identity2"</CODE><CODE> </CODE>;;<BR><CODE>external id : 'a -&gt; 'a = "identity2"</CODE><BR># <B>let</B><CODE> </CODE>a<CODE> </CODE><CODE>=</CODE><CODE> </CODE>id<CODE> </CODE><CODE>[</CODE><CODE>1</CODE>;<CODE>2</CODE>;<CODE>3</CODE>;<CODE>4</CODE>;<CODE>5</CODE><CODE>]</CODE><CODE> </CODE>;;<BR><CODE>val a : int list = [1; 2; 3; 4; 5]</CODE><BR>

</PRE>

We now obtain the expected result.<BR>
<BR>
<A NAME="toc158"></A>
<H3> Calling an Objective CAML closure from C</H3>
<A NAME="sec-Cfermeture"></A>
<A NAME="@fonctions368"></A>
<A NAME="@fonctions369"></A>
<A NAME="@concepts275"></A>
<A NAME="@concepts276"></A>
To apply a closure (i.e. an Objective CAML function value) to one or
several arguments from C, we can use the functions declared in the
header file <TT>callback.h</TT>.
<DIV ALIGN=center>
<TABLE CELLSPACING=2 CELLPADDING=0>
<TR><TD  ALIGN=left NOWRAP><TT>callback(f,v)</TT></TD>
<TD  ALIGN=center NOWRAP>:</TD>
<TD  ALIGN=left NOWRAP>apply the closure <TT>f</TT> to the argument
<TT>v</TT>,</TD>
</TR>
<TR><TD  ALIGN=left NOWRAP><TT>callback2(f,v1,v2)</TT></TD>
<TD  ALIGN=center NOWRAP>:</TD>
<TD  ALIGN=left NOWRAP>same, to two arguments,</TD>
</TR>
<TR><TD  ALIGN=left NOWRAP><TT>callback3(f,v1,v2,v3)</TT></TD>
<TD  ALIGN=center NOWRAP>:</TD>
<TD  ALIGN=left NOWRAP>same, to three arguments,</TD>
</TR>
<TR><TD  ALIGN=left NOWRAP><TT>callbackN(f,n,tbl)</TT></TD>
<TD  ALIGN=center NOWRAP>:</TD>
<TD  ALIGN=left NOWRAP>same, to <TT>n</TT> arguments stored in
the array <TT>tbl</TT>.</TD>
</TR></TABLE>
</DIV>
All these functions return a <TT>value</TT>, which is the result of the
application.<BR>
<BR>

<H4> Registering Objective CAML functions with C</H4>
<A NAME="subsec-register"></A>
<A NAME="@concepts277"></A>
The <TT>callback</TT> functions require the Objective CAML function to be
applied as a closure, that is, as a value that was passed as an argument
to the C function. We can also register a closure from Objective CAML,
giving it a name, then later refer to the closure by its name in a C
function.<BR>
<BR>
The function <TT>register</TT> from module <TT>Callback</TT>
associates a name (of type <TT>string</TT>) with a closure or with any other
Objective CAML value (of any type, that is, <I>'a</I>). This closure or
value can be recovered from C using the C function
<TT>caml_named_value</TT>, which takes a character string as argument
and returns a pointer to the closure or value associated with that
name, if it exists, or the null pointer otherwise.<BR>
<BR>
An example is in order:


<PRE><BR># <B>let</B><CODE> </CODE>plus<CODE> </CODE>x<CODE> </CODE>y<CODE> </CODE><CODE>=</CODE><CODE> </CODE>x<CODE> </CODE><CODE>+</CODE><CODE> </CODE>y<CODE> </CODE>;;<BR><CODE>val plus : int -&gt; int -&gt; int = &lt;fun&gt;</CODE><BR># Callback.register<CODE> </CODE><CODE>"plus3_ocaml"</CODE><CODE> </CODE><TT>(</TT>plus<CODE> </CODE><CODE>3</CODE><TT>)</TT>;;<BR><CODE>- : unit = ()</CODE><BR>

</PRE>



<PRE>
<CODE>#include &lt;caml/mlvalues.h&gt;</CODE><BR><CODE>#include &lt;caml/memory.h&gt;</CODE><BR><CODE>#include &lt;caml/callback.h&gt;</CODE><BR><BR><CODE>value plus3_C (value v) </CODE><BR><CODE>{ </CODE><BR><CODE>  CAMLparam1(v);</CODE><BR><CODE>  CAMLlocal1(f);</CODE><BR><CODE>  f = *(caml_named_value("plus3_ocaml")) ;</CODE><BR><CODE>  CAMLreturn callback(f,v) ;</CODE><BR><CODE>}</CODE><BR>

</PRE>



<PRE><BR># <B>external</B><CODE> </CODE>plusC<CODE> </CODE><CODE>:</CODE><CODE> </CODE>int<CODE> </CODE>-&gt;<CODE> </CODE>int<CODE> </CODE><CODE>=</CODE><CODE> </CODE><CODE>"plus3_C"</CODE><CODE> </CODE>;;<BR><CODE>external plusC : int -&gt; int = "plus3_C"</CODE><BR># plusC<CODE> </CODE><CODE>1</CODE><CODE> </CODE>;;<BR><CODE>- : int = 4</CODE><BR># Callback.register<CODE> </CODE><CODE>"plus3_ocaml"</CODE><CODE> </CODE><TT>(</TT>plus<CODE> </CODE><CODE>5</CODE><TT>)</TT>;;<BR><CODE>- : unit = ()</CODE><BR># plusC<CODE> </CODE><CODE>1</CODE><CODE> </CODE>;;<BR><CODE>- : int = 6</CODE><BR>

</PRE>

Do not confuse the declaration of a C function with <B>external</B>
and the registration of an Objective CAML closure with the function
<TT>register</TT>. In the former case, the declaration is static, the
correspondence between the two names is established at link time.
In the latter case, the binding is dynamic: the correspondence between
the name and the closure is performed at run time. In particular,
the name--closure binding can be modified dynamically by registering a
different closure with the same name, thus modifying the behavior of
C functions using that name.<BR>
<BR>
<HR>
<A HREF="book-ora115.html"><IMG SRC ="previous_motif.gif" ALT="Previous"></A>
<A HREF="index.html"><IMG SRC ="contents_motif.gif" ALT="Contents"></A>
<A HREF="book-ora117.html"><IMG SRC ="next_motif.gif" ALT="Next"></A>
</BODY>
</HTML>
